#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/select.h>
#include <sys/time.h>
#include <string.h>
#include "restart.h"

// test_select中的whichisready函数只能选择fd1和fd2中的一个文件描述符；
// 当 fd1和fd2都准备就绪的情况下，总是选择fd1，这里将copy2file函数推广为输入监控多个文件描述符

int copy2file(int fromfd1, int tofd1, int fromfd2, int tofd2){
    int bytesread, maxfd, num;
    fd_set readset;
    int totalbytes = 0;

    if((fromfd1 < 0) || (fromfd1 >= FD_SETSIZE) ||
        (tofd1 < 0) || (tofd1 > FD_SETSIZE) ||
        (fromfd2 < 0) || (fromfd2 >= FD_SETSIZE) ||
        (tofd2 < 0) || (tofd2 > FD_SETSIZE)){
            return 0;
    }

    maxfd = fromfd1 > fromfd2 ? fromfd1 : fromfd2;        // 为select选择最大的fd
    
    // 在循环中进行阻塞监听
    for( ; ; ){
        FD_ZERO(&readset);
        FD_SET(fromfd1, &readset);
        FD_SET(fromfd2, &readset);

        num = select(maxfd+1, &readset, NULL, NULL, NULL);
        if( num == -1 && errno == EINTR) continue;        // 如果被终端，则继续

        if(num == -1) return totalbytes;

        // 判断进行操作的文件描述符
        if(FD_ISSET(fromfd1, &readset)){
            bytesread = readwrite(fromfd1, tofd1);
            if(bytesread <= 0){
                break;
            }

            totalbytes += bytesread;
        }
        if(FD_ISSET(fromfd2, &readset)){
            bytesread = readwrite(fromfd2, tofd2);
            if(bytesread <= 0){
                break;
            }

            totalbytes += bytesread;
        }
    }

    return totalbytes;
}

int main(int argc, char *argv[]){
	pid_t child_pid;
	int fd, fd1, fd2;
	int bytesread;

	if(argc != 3){
		fprintf(stderr, "Usage: %s file1 file2\n", argv[0]);
		return -1;
	}

	// 此时打开两个文件,此时需要引入头文件fcntl.h
	fd1 = open(argv[1], O_RDONLY);
	if(fd1 == -1){
		fprintf(stderr, "Failed too open file %s:%s\n", argv[1], strerror(errno));
		return 1;
	}
	
	fd2 = open(argv[2], O_RDONLY);
	if(fd2 == -1){
		fprintf(stderr, "Failed too open file %s:%s\n", argv[2], strerror(errno));
		return 1;
	}

    // 将文件中的内容打印到屏幕上
    bytesread = copy2file(fd1, STDOUT_FILENO, fd2, STDOUT_FILENO);
	fprintf(stderr, "Bytes read: %d\n", bytesread);


	return 0;
}